#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

const int N = 2048;
#define ERR_EXIT(m)     \
  do {                  \
    perror(m);          \
    exit(EXIT_FAILURE); \
  } while (0)

class UdpServer {
 public:
  UdpServer(int ser_port) : ser_port_(ser_port) {
    if ((ser_fd_ = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
      ERR_EXIT("socket error");

    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(ser_port_);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(ser_fd_, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
      ERR_EXIT("bind error");
  }
  ~UdpServer() { close(ser_fd_); }
  void Loop() {
    struct sockaddr_in peeraddr;
    socklen_t peerlen;
    int n;

    while (1) {
      peerlen = sizeof(peeraddr);
      memset(buf_recv_, 0, sizeof(buf_recv_));
      n = recvfrom(ser_fd_, buf_recv_, sizeof buf_recv_, 0,
                   (sockaddr *)&peeraddr, &peerlen);
      if (n <= 0) {
        if (errno == EINTR) continue;

        ERR_EXIT("recvfrom error");
      } else if (n > 0) {
        printf("接收到的数据：%s\n", buf_recv_);
        sendto(ser_fd_, buf_recv_, n, 0, (struct sockaddr *)&peeraddr, peerlen);
        printf("回送的数据：%s\n", buf_recv_);
      }
    }
  }

 private:
 private:
  int ser_fd_;
  int ser_port_;
  char buf_recv_[N];
  char buf_sned_[N];
};
int main() {
  UdpServer udp_server(10005);
  udp_server.Loop();
  return 0;
}
// g++ -o udp_ser udp_ser.cc -std=c++11